package template

import (
	"reflect"
	"strings"
	_ "unsafe"
)

type StringMapping func(k string) string

func MapObj(args ...any) StringMapping {
	values := make([]reflect.Value, len(args))
	for i, v := range args {
		field := reflect.ValueOf(v)
		if field.Kind() == reflect.Pointer {
			field = field.Elem()
		}
		values[i] = field
	}

	return func(k string) string {
		if strings.Contains(k, ".") {
			paths := strings.Split(k, ".")
			var field reflect.Value
			for i := range values {
				v := &values[i]
				field = v.FieldByName(paths[0])
				if field.Kind() != reflect.Invalid {
					break
				}
			}
			if field.Kind() == reflect.Pointer {
				field = field.Elem()
			}
			if field.Kind() == reflect.Struct {
				for _, v := range paths[1:] {
					field = field.FieldByName(v)
					if field.Kind() == reflect.Pointer {
						field = field.Elem()
					}
					if field.Kind() != reflect.Struct {
						break
					}
				}
			}
			if field.Kind() == reflect.String {
				return field.String()
			}
		} else {
			for i := range values {
				v := &values[i]
				field := v.FieldByName(k)
				if field.Kind() == reflect.String {
					return field.String()
				}
			}
		}
		return ""
	}
}
